package com.cocos.game;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import androidx.annotation.Nullable;

import com.adjust.sdk.Adjust;
import com.adjust.sdk.AdjustAttribution;
import com.cocos.game.zdkj.log.EventType;
import com.cocos.game.zdkj.log.LogReporter;
import com.cocos.game.zdkj.model.BaseResponse;
import com.cocos.game.zdkj.net.ApiCallBack;
import com.cocos.game.zdkj.net.NetHelper;
import com.cocos.lib.CocosHelper;
import com.cocos.lib.CocosJavascriptJavaBridge;
import com.cocos.service.SDKWrapper;
import com.google.firebase.crashlytics.FirebaseCrashlytics;

import org.json.JSONException;
import org.json.JSONObject;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;

public class Ab_AndroidClient_bA {
    private static final String TAG = "Ab_AndroidClient_bA";

    // 请求token、data
    public static final String REQUEST_TOKEN = "Ab_cc_token_bA";
    public static final String REQUEST_DATA = "Ab_data_bA";

    // 广告
    public static final String API_AD = "Ab_AD_bA";
    public static final String API_REQUEST_DATA_AD_TYPE = "Ab_type_bA";
    public static final String DATA_AD_STATUS = "Ab_status_bA";

    // 设备Id
    public static final String API_DEVICE_ID = "Ab_device_id_bA";
    public static final String DATA_DEVICE_ID = "Ab_device_id_bA";

    // 剪切板
    public static final String API_CLIPBOARD = "Ab_set_clipboard_bA";
    public static final String API_REQUEST_DATA_CLIPBOARD = "Ab_text_bA";

    // 语言、国家
    public static final String API_LOCALLANGUAGE = "Ab_LocalLanguage_bA";
    public static final String DATA_LOCALLANGUAGE_COUNTRY_CODE = "Ab_countryCode_bA";
    public static final String DATA_LOCALLANGUAGE_LANGUAGE_CODE = "Ab_languageCode_bA";

    // 弹窗
    public static final String API_POP = "Ab_float-pop_bA";

    //关闭loading
    public static final String API_CLOSE_LOADING = "Ab_closeLoading_bA"; // TODO: 2024/9/22

    // 打开外链
    public static final String API_OPEN_LINK = "$planet_Link_poof$";
    public static final String REQUEST_DATA_LINK = "$planet_url_poof$";

    public static final String API_FRUIT = "$planet_fruit_poof$";
    public static final String REQUEST_DATA_FRUIT = "$planet_type_poof$";

    // AB面获取
    public static final String API_TYPE = "Ab_type_bA";
    public static final String DATA_TYPE = "Ab_type_bA";

    // 日志上报
    public static final String API_LOG_REPORT = "Ab_POINT_bA"; // TODO: 2024/9/22
    public static final String API_REQUEST_DATA_LOG_EVENT = "Ab_point_bA";
    public static final String API_REQUEST_DATA_LOG_PARAMS = "Ab_value_bA";

    public static final String[] ADJUST_NETWORK_A = {"Unknown Devices", "Untrusted Devices", "Organic"};

    public static void Ab_callNative_bA(String api, String params) {
        Log.d(TAG, "CocosCall:" + api + "\n" + params);
        JSONObject request = null;

        try {
            request = new JSONObject(params);
            JSONObject requestData = request.getJSONObject(REQUEST_DATA);

            JSONObject response = new JSONObject();
            response.put(REQUEST_TOKEN, request.getString(REQUEST_TOKEN));
            JSONObject responseData = new JSONObject();
            response.put(REQUEST_DATA, responseData);
            switch (api) {
                case API_TYPE:
                    if (MApplication.isReturnTest){
                        responseData.put(DATA_TYPE, "Test");
                        callCocos(api, response);
                        return;
                    }
                    // 获取AB版本 优先从缓存中获取
                    if (MAppCacheManager.getAppType() != null) {
                        responseData.put(DATA_TYPE, MAppCacheManager.getAppType());
                        callCocos(api, response);
                    } else {
                        getAuditTypeByAdjust(api, response, responseData);
                    }
                    return;
                case API_DEVICE_ID:
                    // 获取设备Id
                    String deviceId = DeviceUtil.getDeviceId();
                    responseData.put(DATA_DEVICE_ID, deviceId);
                    callCocos(api, response);
                    return;
                case API_CLIPBOARD:
                    String text = requestData.getString(API_REQUEST_DATA_CLIPBOARD);
                    setClipboard(MApplication.instance, text);
                    return;
                case API_AD:
                    String adType = requestData.getString(API_REQUEST_DATA_AD_TYPE);
                    // 激励广告
                    if (adType.equals("incentive")) {
                        putAdRequest(API_AD, AdType.Rewarded, request);
                        playAd(AdType.Rewarded);
                    } else if (adType.equals("full-screen")) {
                        putAdRequest(API_AD, AdType.Interstitial, request);
                        playAd(AdType.Interstitial);
                    }
                    return;
                case API_LOCALLANGUAGE:
                    Locale systemLocale;
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        systemLocale = MApplication.instance.getResources().getConfiguration().getLocales().get(0);
                    } else {
                        systemLocale = Locale.getDefault();
                    }
                    // 获取设备Id
                    responseData.put(DATA_LOCALLANGUAGE_COUNTRY_CODE, systemLocale.getCountry());
                    responseData.put(DATA_LOCALLANGUAGE_LANGUAGE_CODE, systemLocale.getLanguage());
                    callCocos(api, response);
                    return;
                case API_POP:
                    showPop();
                    return;
                case API_CLOSE_LOADING:
                    showLoading(false);
                    return;
                case API_LOG_REPORT:
                    String logEventId = requestData.getString(API_REQUEST_DATA_LOG_EVENT);
                    String logParams = requestData.getString(API_REQUEST_DATA_LOG_PARAMS);
                    LogReporter.logHelpCocosReport(logEventId, logParams);
                    return;
            }
        } catch (JSONException e) {
            if (MApplication.DEBUG()) {
                throw new RuntimeException(e);
            }
        }

    }

    public static void showLoading(boolean isLoading) {
        if (SDKWrapper.shared().getActivity() instanceof BaseAdActivity) {
            Handler mainHandler = new Handler(Looper.getMainLooper());
            // 使用主线程的Handler更新UI
            mainHandler.post(() -> {
                BaseAdActivity baseAdActivity = (BaseAdActivity) SDKWrapper.shared().getActivity();
                baseAdActivity.hideSplash();
                baseAdActivity.updateLoadingState(isLoading, true);
            });
        }
    }

    /**
     * adjust 获取归因结果后调用，从服务端获取最新归因结果
     *
     * @param api          cocosApi
     * @param response     cocosResponse
     * @param responseData cocosResponseData
     * @param network      network
     */
    private static void getBusinessTypeFromServer(String api, JSONObject response, JSONObject responseData, String network) {
        boolean isPhone = true;
        try {
            if (ZDKJUtils.isTablet(SDKWrapper.shared().getActivity())) {
                isPhone = false;
            }
        } catch (Throwable throwable) {
            Log.d(TAG, "判断非手机失败", throwable);
        }

        boolean isOpenProxy = false;
        try {
            if (NetworkProxyUtil.hasVPN(MApplication.instance) || NetworkProxyUtil.isWifiProxyEnabled(MApplication.instance)) {
                isOpenProxy = true;
            }
        } catch (Throwable throwable) {
            Log.d(TAG, "判断使用代理上网失败", throwable);
        }

        boolean isOpenDev = false;
        try {
            if (ZDKJUtils.isOpenDevelopmentSetting(MApplication.instance)) {
                isOpenDev = true;
            }
        } catch (Throwable throwable) {
            Log.d(TAG, "判断开启开发者选项失败", throwable);
        }
        // 2024/8/24 获取归因成功回调
        boolean finalIsPhone = isPhone;
        boolean finalIsOpenProxy = isOpenProxy;
        boolean finalIsOpenDev = isOpenDev;
        NetHelper.getInstance().getBusinessType(isPhone, isOpenProxy, isOpenDev, new ApiCallBack() {
            @Override
            protected void onComplete() {

            }

            @Override
            protected void onSuccess(@Nullable BaseResponse data) {
                try {
                    String appType = data.getResult();
                    MAppCacheManager.setAppType(appType);
                    responseData.put(DATA_TYPE, appType);
                    callCocos(api, response);
                    Map<String, String> extParams = new HashMap<>();
                    extParams.put("showSide", appType);
                    extParams.put("judgeType", "server");
                    extParams.put("message", data.getCode() + "-" + data.getMessage());
                    LogReporter.logReport(EventType.judge_side, extParams);
                    NetHelper.getInstance().reportBusinessType(appType, network, finalIsPhone, finalIsOpenProxy, finalIsOpenDev, new ApiCallBack() {
                        @Override
                        protected void onComplete() {

                        }

                        @Override
                        protected void onSuccess(@Nullable BaseResponse data) {

                        }

                        @Override
                        protected void onError(int code, String message) {

                        }
                    });
                } catch (Throwable e) {
                    FirebaseCrashlytics.getInstance().recordException(e);
                }
            }

            @Override
            protected void onError(int code, String message) {
                try {
                    MAppCacheManager.setAppType("B");
                    responseData.put(DATA_TYPE, "B");
                    callCocos(api, response);
                    Map<String, String> extParams = new HashMap<>();
                    extParams.put("showSide", "B");
                    extParams.put("judgeType", "default");
                    extParams.put("message", code + "-" + message);
                    LogReporter.logReport(EventType.judge_side, extParams);
                } catch (Throwable e) {
                    FirebaseCrashlytics.getInstance().recordException(e);
                }
            }
        });

    }

    public static void getAuditTypeByAdjust(String api, JSONObject response, JSONObject responseData) throws JSONException {
//        showLoading(true);
        AtomicReference<AdjustAttribution> adjustAttributionAtomicReference = new AtomicReference<>();
        Adjust.getAttribution(adjustAttribution -> {
            Log.d(TAG, "Adjust isAdjustInit: " + true + " attr: " + adjustAttribution);
            adjustAttributionAtomicReference.set(adjustAttribution);
        });
        {
            final Handler handler = new Handler(Looper.getMainLooper());
            final AtomicLong elapsedTime = new AtomicLong(0); // To track elapsed time
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    elapsedTime.addAndGet(200); // Increment by 100ms on each execution
                    // 获取归因成功
                    if (adjustAttributionAtomicReference.get() != null && adjustAttributionAtomicReference.get().network != null) {
                        String abType = getAuditByAdjustNetwork(adjustAttributionAtomicReference.get().network);
                        LogReporter.logAppType("A".equals(abType) ? LogReporter.ABResultType.FAIL : LogReporter.ABResultType.SUCCESS, adjustAttributionAtomicReference.get().network);
                        if ("A".equals(abType)) {
                            try {
                                MAppCacheManager.setAppType(abType);
                                responseData.put(DATA_TYPE, abType);
                                callCocos(api, response);
                            } catch (Throwable e) {
                                FirebaseCrashlytics.getInstance().recordException(e);
                            }
                        } else {
                            getBusinessTypeFromServer(api, response, responseData, adjustAttributionAtomicReference.get().network);
                        }

                        handler.removeCallbacks(this); // Remove this callback to stop further executions
                    } else if (elapsedTime.get() >= 10 * 1000) {
                        // 获取归因未成功且超时
                        handler.removeCallbacks(this); // Remove this callback to stop further executions
                        LogReporter.logAppType(LogReporter.ABResultType.DELAY, null);
                        // 2024/8/24  超过10s获取归因失败回调
                        try {
                            String appType = getAuditByAdjustNetwork(ADJUST_NETWORK_A[0]);
                            MAppCacheManager.setAppType(appType);
                            responseData.put(DATA_TYPE, appType);
                            callCocos(api, response);
                        } catch (JSONException ignored) {
                        }
//                        showLoading(false);
                    } else {
                        // 获取归因未成功，且未超时 继续轮询
                        handler.postDelayed(this, 200);
                    }
                }
            };
            handler.postDelayed(runnable, 200);
        }
    }

    public static String getAuditByAdjustNetwork(String network) {
        if (MApplication.isReturnB) {
            return "B";
        }
        for (String s : ADJUST_NETWORK_A) {
            if (s.equals(network)) {
                return "A";
            }
        }
        return "B";
    }

    public static String getFirstAuditType() {
        if (MApplication.isReturnB) {
            return "B";
        }
        // 国家或语言是韩国 返回 A
        Locale systemLocale;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            systemLocale = MApplication.instance.getResources().getConfiguration().getLocales().get(0);
        } else {
            systemLocale = Locale.getDefault();
        }
        if ("KR".equalsIgnoreCase(systemLocale.getCountry()) || "ko".equalsIgnoreCase(systemLocale.getLanguage())) {
            Log.d(TAG, "type优先-国家或语言");
            return "A";
        }
        // 非手机 返回 A
        try {
            if (ZDKJUtils.isTablet(SDKWrapper.shared().getActivity())) {
                Log.d(TAG, "type优先-判断非手机");
                return "A";
            }
        } catch (Throwable throwable) {
            Log.d(TAG, "判断非手机失败", throwable);
        }

        // 使用代理 返回 "A"
        try {
            if (NetworkProxyUtil.hasVPN(MApplication.instance) || NetworkProxyUtil.isWifiProxyEnabled(MApplication.instance)) {
                Log.d(TAG, "type优先-判断使用代理上网");
                return "A";
            }
        } catch (Throwable throwable) {
            Log.d(TAG, "判断使用代理上网失败", throwable);
        }

        // 开启开发者选项 返回 "A"
        try {
            if (ZDKJUtils.isOpenDevelopmentSetting(MApplication.instance)) {
                Log.d(TAG, "type优先-判断开启开发者选项");
                return "A";
            }
        } catch (Throwable throwable) {
            Log.d(TAG, "判断开启开发者选项失败", throwable);
        }

        return null;
    }

    public static String getAuditTypeByTime(String auditEndTime) {
        long currentTimeMillis = System.currentTimeMillis();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
        try {
            // 将指定时间字符串转换为Date对象
            Date dateSpecified = sdf.parse(auditEndTime);
            // 比较当前时间和指定时间
            assert dateSpecified != null;
            if (currentTimeMillis > dateSpecified.getTime()) {
                Log.d(TAG, "当前时间晚于指定时间");
                return "B";
            } else {
                Log.d(TAG, "当前时间早于指定时间");
                return "A";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "B";
    }

    private static void callCocos(String api, JSONObject response) {
        Log.d(TAG, "CallCocos:" + api + "\n" + response);
        CocosHelper.runOnGameThread(() -> CocosJavascriptJavaBridge.evalString("Ab_AndroidClient_bA.Ab_response_bA('"
                + api
                + "','"
                + response
                + "')"));
    }

    public static void setClipboard(Context context, String text) {
        ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
        if (clipboard != null) {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
                // For versions lower than Honeycomb, use the deprecated setText method.
                clipboard.setText(text);
            } else {
                ClipData clip = ClipData.newPlainText("Copied Text", text);
                clipboard.setPrimaryClip(clip);
            }
        }
    }

    public static void playAd(AdType adType) {
        Log.d(TAG, "playAd:" + adType.name());

        if (SDKWrapper.shared().getActivity() instanceof BaseAdActivity) {
            Handler mainHandler = new Handler(Looper.getMainLooper());
            // 使用主线程的Handler更新UI
            mainHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    BaseAdActivity baseAdActivity = (BaseAdActivity) SDKWrapper.shared().getActivity();
                    if (adType == AdType.Rewarded) {
                        baseAdActivity.showRewardedAd();
                    } else if (adType == AdType.Interstitial) {
                        baseAdActivity.showInterstitialAd();
                    }
                }
            }, 1800);

        } else {
            if (MApplication.DEBUG()) {
                throw new RuntimeException("AdActivity is not BaseAdActivity");
            }
        }
    }

    public static void showPop() {
        Log.d(TAG, "showPop");
        if (SDKWrapper.shared().getActivity() instanceof BaseAdActivity) {
            // 主线程中的Handler
            Handler mainHandler = new Handler(Looper.getMainLooper());
            // 使用主线程的Handler更新UI
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    // 更新UI的代码
                    BaseAdActivity baseAdActivity = (BaseAdActivity) SDKWrapper.shared().getActivity();
                    baseAdActivity.showPop();
                }
            });

        } else {
            if (MApplication.DEBUG()) {
                throw new RuntimeException("AdActivity is not BaseAdActivity");
            }
        }
    }

    public static void putAdRequest(String api, AdType adType, JSONObject request) {
        ConcurrentLinkedQueue<JSONObject> queue = MApplication.getRequestQueue(api + adType.name());
        boolean result = queue.offer(request);
        Log.d(TAG, "putAdRequest:" + result + "  queueName:" + api + adType.name() + " \nrequest:" + request);

    }

    public static void onAdPlayError(AdType adType) {

        JSONObject request = MApplication.getRequestQueue(API_AD + adType.name()).poll();
        Log.d(TAG, "queueName:" + API_AD + adType.name() + " \nrequest:" + request);

        if (request == null) {
            return;
        }
        JSONObject response = new JSONObject();
        try {
            response.put(REQUEST_TOKEN, request.getString(REQUEST_TOKEN));
            JSONObject data = new JSONObject();
            data.put(DATA_AD_STATUS, "ad-error");
            response.put(REQUEST_DATA, data);
            Ab_AndroidClient_bA.callCocos(API_AD, response);
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }

    }

    public static void onAdPlayOver(AdType adType) {

        JSONObject request = MApplication.getRequestQueue(API_AD + adType.name()).poll();
        Log.d(TAG, "queueName:" + API_AD + adType.name() + " \nrequest:" + request);
        if (request == null) {
            return;
        }
        JSONObject response = new JSONObject();
        try {
            response.put(REQUEST_TOKEN, request.getString(REQUEST_TOKEN));
            JSONObject data = new JSONObject();
            data.put(DATA_AD_STATUS, "ad-over");
            response.put(REQUEST_DATA, data);
            Ab_AndroidClient_bA.callCocos(API_AD, response);
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
    }

}